#include "Scene_PCH.h"
#include "Scene.h"

/*--------------------------------------------------------------------------*/

IScene* g_Scene = NULL;

/*--------------------------------------------------------------------------*/

CScene::CScene() :
	IThread("SceneThread", 60.0f, EThread::SynchronizeBeforeRendering),
	m_allowCameraMovement(true),
	m_worldMgr(NULL),
	m_skydomeMgr(NULL)
{
	g_Renderer->AddTypeRenderer(this, "opq", 0);
	g_Renderer->AddTypeRenderer(this, "lit", 1);
	g_Renderer->AddTypeRenderer(this, "sky", 2);

	m_freeCamera = new Camera(glm::vec4(0.0f, 0.0f, g_Renderer->GetResX(), g_Renderer->GetResY()), 100000.0f, 1.0f, 60.0f);
	m_freeCamera->SetWorldPosition(glm::vec3(0.0f, 0.0f, 120.0f));
}

/*--------------------------------------------------------------------------*/

CScene::~CScene()
{
	delete m_skydomeMgr;
	delete m_worldMgr;
	delete m_freeCamera;
}

/*--------------------------------------------------------------------------*/

void CScene::RenderType( uint arg )
{
	switch (arg)
	{
	case 0: // opq
		{
			g_Renderer->GetQueueMgr()->ClearQueue();
			RenderOpaque();
			g_Renderer->GetQueueMgr()->Flush();
			break;
		}
	case 1: // lit
		{
			g_Renderer->GetQueueMgr()->ClearQueue();
			RenderLights();
			g_Renderer->GetQueueMgr()->Flush();
			break;
		}
	case 2: //sky
		{
			RenderSkydome();
			break;
		}
	}
}

/*--------------------------------------------------------------------------*/

void CScene::RenderOpaque()
{
	MoveFreeCamera();
	ApplyCamera(m_freeCamera);

	GetWorldMgr()->RenderOpaque();

	glm::vec3 c = m_freeCamera->GetWorldPosition();

	RMaterial* m = g_Renderer->GetRendererStorageMgr()->GetMaterial("default_all");
	g_Renderer->BindMaterial(m);

	std::string campos = "Camera = [" + std::to_string(c.x) + ", " + std::to_string(c.y) + ", " + std::to_string(c.z) + "]";
	g_UserInterface->AddMessage(campos);
	g_UserInterface->AddMessage("rendering opq");
}

/*--------------------------------------------------------------------------*/

void CScene::RenderLights()
{
	ApplyCamera(m_freeCamera);
	g_UserInterface->AddMessage("rendering lit");
}

/*--------------------------------------------------------------------------*/

void CScene::RenderSkydome()
{
	ApplyCamera(m_freeCamera);

	GetSkydomeMgr()->RenderSky(m_freeCamera);
	g_UserInterface->AddMessage("rendering skydome");
}

/*--------------------------------------------------------------------------*/

void CScene::ApplyCamera( Camera* camera )
{
	if (camera)
	{
		g_Renderer->SetCamera(camera->GetViewMatrix(), camera->GetProjectionMatrix(), camera->GetNearDistance(), camera->GetFarDistance(), camera->GetWorldPosition());
	}
}

/*--------------------------------------------------------------------------*/

void CScene::MoveFreeCamera()
{
	if (g_Input->GetKeyState(SDLK_w))
	{
		m_freeCamera->MoveZ(-0.1f);
	}
	
	if (g_Input->GetKeyState(SDLK_s))
	{
		m_freeCamera->MoveZ(0.1f);
	}

	if (g_Input->GetKeyState(SDLK_a))
	{
		m_freeCamera->MoveX(-0.1f);
	}

	if (g_Input->GetKeyState(SDLK_d))
	{
		m_freeCamera->MoveX(0.1f);
	}

	if (g_Input->GetKeyState(SDLK_r))
	{
		m_freeCamera->MoveY(0.1f);
	}

	if (g_Input->GetKeyState(SDLK_f))
	{
		m_freeCamera->MoveY(-0.1f);
	}

	if (g_Input->GetKeyState(SDLK_UP))
	{
		m_freeCamera->AddRotationX(-0.1f);
	}

	if (g_Input->GetKeyState(SDLK_DOWN))
	{
		m_freeCamera->AddRotationX(0.1f);
	}

	if (g_Input->GetKeyState(SDLK_LEFT))
	{
		m_freeCamera->AddRotationY(-0.1f);
	}

	if (g_Input->GetKeyState(SDLK_RIGHT))
	{
		m_freeCamera->AddRotationY(0.1f);
	}

	if (g_Input->GetKeyState(SDLK_q))
	{
		m_freeCamera->AddRotationZ(-0.1f);
	}

	if (g_Input->GetKeyState(SDLK_e))
	{
		m_freeCamera->AddRotationZ(0.1f);
	}

}

/*--------------------------------------------------------------------------*/

void CScene::InitializeScene()
{
	m_worldMgr = new WorldMgr();
	m_skydomeMgr = new SkydomeMgr();

	m_worldMgr->InitWorldMgr();
	m_worldMgr->SetGravity(glm::vec3(0.0f, -10.0f, 0.0f));

	m_worldMgr->AddBorderPlane("GroundBorder", glm::vec3(0.0f, 1.0f, 0.0f), -499.0f);

	StartThread();
}

/*--------------------------------------------------------------------------*/

WorldMgr* CScene::GetWorldMgr()
{
	return m_worldMgr;
}

/*--------------------------------------------------------------------------*/

SkydomeMgr* CScene::GetSkydomeMgr()
{
	return m_skydomeMgr;
}

/*--------------------------------------------------------------------------*/

int CScene::ThreadLoop()
{
	GetWorldMgr()->CalculatePhysics();

	return 0;
}

/*--------------------------------------------------------------------------*/
